/**
 * @addtogroup sfc_task.h
 * sfc_task.h
 * @{
 */
/**
 * @file sfc_task.h
 * @brief 定义Task类
 * @note
 * @author Leo
 * @date 2020-11-19
 * @version 1.1

 * @par          修改日志
 * <table>
 * <tr><th>Date <th>Version <th>Author <th> Description
 * <tr><td>2019-07-03 <td>1.0 <td>Leo <td> 创建初始版本
 * <tr><td>2020-11-19 <td>1.1 <td>Leo <td> 销毁任务对象时,如果任务不是处于停止状态,则强行结束线程
 * <tr><td>2020-12-22 <td>1.2 <td>Leo <td> 加入TSfTaskThread函数
 * @copyright 杭州鸿泉物联网技术股份有限公司
 */
#ifndef _SFC_TASK_H_
#define _SFC_TASK_H_

#include <ofc_object.h>
#include "sfc_thread.h"

#ifdef __cplusplus
extern "C" {
#endif

/** 任务状态 */
typedef enum TSfTaskStateTag TSfTaskState;
enum TSfTaskStateTag
{
    kSfTaskStateStopped,  ///< 任务处于停止状态
    kSfTaskStateStart,  ///< 任务开始执行
    kSfTaskStateRunning,  ///< 任务处于运行状态
    kSfTaskStateStop,  ///< 任务停止执行
    kSfTaskStateStopping,  ///< 任务正在停止
};


/**
 * 构造一个任务基类
 * @par 示例
 * @code
    typedef struct TMainTaskTag TMainTask;
    struct TMainTaskTag
    {
    PROTECTED
        TSfTask parent_;
        TOfVirtualMethod Destroy_;

    PUBLIC

    PRIVATE

    };

    static void TMainTaskDestroy(TOfObject *object)
    {
        TMainTask *self = (TMainTask *)object;

        self->Destroy_(object);
    }

    static void TMainTaskOnCreate( TOfObject *sender )
    {
        TMainTask *self = (TMainTask *)sender;

        // TODO : ...
    }

    static void TMainTaskOnExecute( TOfObject *sender )
    {
        TMainTask *self = (TMainTask *)sender;

        while (!TSfTaskTerminated((TSfTask *)self))
        {
            // TODO : ...
            SfSleep(50);  
        }   
    }

    void TMainTaskCreate( TMainTask *self )
    {
        __align(8) static char stack[512];

        TSfTaskCreate((TSfTask *)self, kSfThreadPriorityNormal, stack, sizeof(stack));
        OVERRIDE_METHOD(TOfObject, Destroy, TMainTaskDestroy);

        self->parent_.OnCreate = TMainTaskOnCreate;
        self->parent_.OnExecute = TMainTaskOnExecute;
    }

    TMainTask task;
    TMainTaskCreate(&task);
    TSfTaskResume((TSfTask *)&task);
    TSfTaskStart((TSfTask *)&task);
    ...
    TSfTaskStop((TSfTask *)&task);
    TSfTaskWaitFor((TSfTask *)&task, 5000);
    
    OfDestroyObject((TObject *)&task);
    

 * @endcode
*/

typedef struct TSfTaskTag TSfTask;
struct TSfTaskTag
{
PROTECTED
    TOfObject parent_;
    TOfVirtualMethod Destroy_;

PUBLIC
    TOfNotifyEvent OnCreate;  ///< 线程启动后立即执行的事件
    TOfNotifyEvent OnStart;  ///< 任务开始时执行的事件
    TOfNotifyEvent OnExecute;  ///< 任务运行事件
    TOfNotifyEvent OnStop;  ///< 任务停止后执行的事件

PRIVATE
    TSfThread thread_;  ///< 任务的执行线程
    TSfTaskState state_;  ///< 任务状态
};

/**
 * 任务类的构造函数
 * @param self: 对象实例指针
 * @param priority: 任务线程的优先级
 * @param stack: 任务线程的堆栈,可以为空,用默认的堆栈; 注意: 线程的堆栈必须是8字节对齐的,既: 堆栈的起始地址必须是8的倍数
 * @param stack_size: 任务线程的堆栈大小,可以为0,用默认的堆栈大小
 * @return 返回创建是否成功; 创建成功返回True,参数错误(堆栈起始地址不是8字节对齐)则创建失败返回False
 */
Bool TSfTaskCreate(TSfTask *self, TSfThreadPriority priority, void *stack, Int32 stack_size);

/**
 * 创建任务对象
 * @param priority: 任务线程的优先级
 * @param stack: 任务线程的堆栈,可以为空,用默认的堆栈; 注意: 线程的堆栈必须是8字节对齐的,既: 堆栈的起始地址必须是8的倍数
 * @param stack_size: 任务线程的堆栈大小,可以为0,用默认的堆栈大小
 * @return 创建成功返回创建的对象,创建失败返回NULL
 */
TSfTask *SfCreateTask(TSfThreadPriority priority, void *stack, Int32 stack_size);

/**
 * 任务类的构造函数(使用线程属性)
 * @param self: 对象实例指针
 * @param attr: 线程属性
 * @return 返回创建是否成功; 创建成功返回True,参数错误(堆栈起始地址不是8字节对齐)则创建失败返回False
 */
Bool TSfTaskCreateEx(TSfTask *self, const TSfThreadAttr *attr);

/**
 * 创建任务对象(使用线程属性)
 * @param attr: 线程属性
 * @return 创建成功返回创建的对象,创建失败返回NULL
 */
TSfTask *SfCreateTaskEx(const TSfThreadAttr *attr);

/**
 * 任务在创建后挂起,使任务恢复运行
 * @param self: 对象实例
 * @return 创建失败返回False,创建成功返回True
 */
Bool TSfTaskResume(TSfTask *self);

Bool TSfTaskResumeEx(TSfTask *self, TSfThreaResumedAttr *resume_attr);

/**
 * 任务开始运行.
 * @param self: 对象实例
 * @return 无返回值
 */
void TSfTaskStart(TSfTask *self);

/**
 * 停止任务.
 * @note 需要[TSfTaskWaitFor](@ref TSfTaskWaitFor)来等待任务结束
 * @param self: 对象实例
 * @return 无返回值
 */
void TSfTaskStop(TSfTask *self);

/**
 * 返回当前任务是否在运行
 * @param self: 对象实例
 * @return 任务在运行返回true,否则为false
 */
Bool TSfTaskRunning(TSfTask *self);

/**
 * 返回当前任务是否已停止
 * @param self: 对象实例
 * @return 任务在运行返回true,否则为false
 */
Bool TSfTaskStopped(TSfTask *self);

/**
 * 判断当前任务是否需要结束
 * @note: 本函数应该在OnExecute中调用来判断是否需要停止
 * @param self: 对象实例
 * @return 任务需要结束返回true,否则返回false
 */
Bool TSfTaskTerminated(TSfTask *self);

/**
 * 等待任务停止.
 * @param self: 对象实例
 * @param timeout: 等待时长,单位: ms
 * @return 在timeout时间内任务停止返回True,否则返回False
 */
Bool TSfTaskWaitFor(TSfTask *self, Int32 timeout);

/**
 * 返回当前任务的执行线程
 * @param self: 对象实例
 * @return 返回任务的执行线程
 */
const TSfThread *TSfTaskThread(TSfTask *self);

#ifdef __cplusplus
}  // extern "C"
#endif

#endif  // _SFC_TASK_H_

/**
 * @}
 */
